package com.dyna.cp.binlog;

import cn.hutool.core.collection.CollUtil;
import com.dyna.constants.StringPool;
import org.springframework.stereotype.Component;

import javax.validation.constraints.NotNull;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class BingLogMetadata {

    public static Map<String, Map<Integer,String>> database(BinLogConstants binLog) throws Exception{
        Map<String,Map<Integer,String>> metadata = new ConcurrentHashMap<>();
        List<String> table = binLog.getTables();
        if(CollUtil.isNotEmpty(table)){
            Map<String, List<String>> group = getStringListMap(table);
            for (Map.Entry<String, List<String>> next : group.entrySet()) {
                String key = next.getKey();
                List<String> value = next.getValue();
                Properties props = new Properties();
                props.setProperty("user", binLog.getUsername());
                props.setProperty("password", binLog.getPasswd());
                props.setProperty("remarks", "true");
                props.setProperty("useInformationSchema", "true");
                String url = "jdbc:mysql://" + binLog.getHost() + ":" + binLog.getPort() + "/" + key + "?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8";
                Connection connection = DriverManager.getConnection(url, props);
                DatabaseMetaData metaData = connection.getMetaData();
                ResultSet tableRs = metaData.getTables(connection.getCatalog(), connection.getCatalog(), "%", new String[]{"TABLE"});
                while (tableRs.next()) {
                    String tableName = tableRs.getString("TABLE_NAME");
                    if (value.contains(tableName)) {
                        Map<Integer, String> map = new HashMap<>();
                        metadata.put(key + "." + tableName, map);
                        ResultSet columnRs = metaData.getColumns(connection.getCatalog(), connection.getCatalog(), tableName, "%");
                        int i = 0;
                        while (columnRs.next()) {
                            map.put(i, columnRs.getString("COLUMN_NAME"));
                            i++;
                        }
                    }
                }
            }
        }
        return metadata;
    }

    @NotNull
    private static Map<String, List<String>> getStringListMap(List<String> table) throws Exception {
        Map<String,List<String>> group = new ConcurrentHashMap<>();
        for (String key : table) {
            String[] split = key.split(StringPool.BACK_SLASH + StringPool.DOT);
            if (split.length != 2) {
                throw new Exception("BinLog配置同步,类型错误 [库名.表名]。请正确配置:" + key);
            }
            String database = split[0];
            String tableName = split[1];
            List<String> list = group.computeIfAbsent(database, k -> new ArrayList<>());
            list.add(tableName);
        }
        return group;
    }

}
